package com.cacche;

import android.graphics.Bitmap;
import android.support.v4.util.LruCache;
import android.text.TextUtils;

import java.lang.ref.SoftReference;
import java.util.LinkedHashMap;


/**
 * @Title: ImageMemoryCache.java
 * @Package com.yiliao.android.mediawall.util
 * @Description: TODO(添加描述)
 * @author 刘章
 * @date 2013-2-1 上午1:30:34
 */
public class PhotoMemoryCache
{
	
	private static PhotoMemoryCache                                   instance;
	
	//开辟8M硬缓存空间
	private final int                                                 hardCachedSize      = 8 * 1024 * 1024;
	
	private final LruCache<String, Bitmap>                            sHardBitmapCache    = new LruCache<String, Bitmap>(hardCachedSize)
	                                                                                      {
		                                                                                      
		                                                                                      @Override
		                                                                                      protected int sizeOf(String key, Bitmap value) {
			                                                                                      int size = value.getRowBytes() * value.getHeight();
			                                                                                      Cache.log("sizeOf=" + size);
			                                                                                      return size;
		                                                                                      }
		                                                                                      
		                                                                                      @Override
		                                                                                      protected void entryRemoved(boolean evicted, String key, Bitmap oldValue, Bitmap newValue) {
			                                                                                      //硬引用缓存区满，将一个最不经常使用的oldvalue推入到软引用缓存区
			                                                                                      Cache.log("entryRemoved=" + key);
			                                                                                      sSoftBitmapCache.put(key, new SoftReference<Bitmap>(oldValue));
			                                                                                      
			                                                                                      Cache.log("memorySize entryRemoved:" + size() + " length:" + putCount());
		                                                                                      }
		                                                                                      
	                                                                                      };
	
	//软引用
	public static final int                                           SOFT_CACHE_CAPACITY = 200;
	
	private final static LinkedHashMap<String, SoftReference<Bitmap>> sSoftBitmapCache    = new LinkedHashMap<String, SoftReference<Bitmap>>(SOFT_CACHE_CAPACITY, 0.75f, true)
	                                                                                      {
		                                                                                      
		                                                                                      private static final long serialVersionUID = -861871891767010L;
		                                                                                      
		                                                                                      @Override
		                                                                                      public SoftReference<Bitmap> put(String key, SoftReference<Bitmap> value) {
			                                                                                      return super.put(key, value);
		                                                                                      }
		                                                                                      
		                                                                                      @Override
		                                                                                      protected boolean removeEldestEntry(Entry<String, SoftReference<Bitmap>> eldest) {
			                                                                                      return size() > SOFT_CACHE_CAPACITY;
		                                                                                      }
		                                                                                      
	                                                                                      };
	
	private PhotoMemoryCache() {
		
	}
	
	public static PhotoMemoryCache getInstance() {
		if (instance == null)
		{
			instance = new PhotoMemoryCache();
		}
		return instance;
	}
	
	//缓存bitmap
	public boolean putBitmap(String key, Bitmap bitmap) {
		if (key != null && bitmap != null)
		{
			synchronized (sHardBitmapCache)
			{
				Cache.log("putBitmap=" + key);
				sHardBitmapCache.put(key, bitmap);
				Cache.log("memorySize putBitmap:" + sHardBitmapCache.size());
			}
			return true;
		}
		return false;
	}
	
	//从缓存中获取bitmap
	public Bitmap getBitmap(String key) {
		if (key == null) { return null; }
		synchronized (sHardBitmapCache)
		{
			final Bitmap bitmap = sHardBitmapCache.get(key);
			if (bitmap != null)
			{
				Cache.log("from hard cache:" + key);
				return bitmap;
			}
		}
		//硬引用缓存区间中读取失败，从软引用缓存区间读取
		synchronized (sSoftBitmapCache)
		{
			Cache.log("try load from soft cache:" + key);
			SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.get(key);
			if (bitmapReference != null)
			{
				final Bitmap bitmap2 = bitmapReference.get();
				if (bitmap2 != null)
				{
					Cache.log("from soft cache:" + key);
					return bitmap2;
				}
				else
				{
					Cache.log("回收:" + key);
					sSoftBitmapCache.remove(key);
				}
			}
		}
		return null;
		
	}
	
	public boolean removeBitmap(String key) {
		if (TextUtils.isEmpty(key)) return false;
		Bitmap bitmap = null;
		synchronized (sHardBitmapCache)
		{
			bitmap = sHardBitmapCache.remove(key);
		}
		if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle();
		synchronized (sSoftBitmapCache)
		{
			SoftReference<Bitmap> bitmapReference = sSoftBitmapCache.remove(key);
			if (bitmapReference != null)
			{
				bitmap = bitmapReference.get();
				bitmapReference.clear();
			}
		}
		if (bitmap != null && !bitmap.isRecycled()) bitmap.recycle();
		return true;
	}
	
	//清理
	public void clear() {
		synchronized (sHardBitmapCache)
		{
			//sHardBitmapCache.
		}
		synchronized (sSoftBitmapCache)
		{
			Cache.log("回收!");
			sSoftBitmapCache.clear();
		}
	}
}
